from __future__ import absolute_import, division

from gui.panda.base import *

from ..utils import Heightfield, ValueField
from .water import WaterPlane


class PNMField(PNMImage):
    def __init__(self, array):
        super(PNMField, self).__init__(array.shape[0], array.shape[1])
        
        for x in range(array.shape[0]):
            for y in range(array.shape[1]):
                self.setXel(x, array.shape[1] - y - 1, array[x, y])


class TerrainPlane(Object):
    parent    = Attribute()
    size      = Attribute()
    geo       = Attribute()
    resources = Attribute()
    camera    = Attribute()
    
    map           = Attribute()
    heightfield   = map._.heightfield
    fertility_map = map._.fertility_map
    
    terrain     = Attribute()
    ocean       = Attribute()
    lakes       = Attribute()
    
    @property
    def root(self):
        return self.terrain.getRoot()
    
    def setup(self):
        self.terrain = GeoMipTerrain('terrain')
        self.ocean   = WaterPlane(self.parent, 'ocean', self.size - 1, self.resources, 2.0)
        
        self.terrain.setHeightfield(PNMField(self.heightfield))
        self.terrain.setBlockSize(32)
        self.terrain.setNear(1000)
        self.terrain.setFar(5000)
        self.terrain.setFocalPoint(self.camera)
        
        self.root.reparentTo(self.parent)
        self.root.setSz(5)
        self.root.setPos(0, 0, 0)
        
        self.terrain.generate()
        
        self.root.setTexture(TextureStage('sand'),      self.resources.load_terrain('Sand'),      1)
        self.root.setTexture(TextureStage('grass'),     self.resources.load_terrain('Grass'),     2)
        self.root.setTexture(TextureStage('infertile'), self.resources.load_terrain('Infertile'), 3)
        
        texture = Texture()
        texture.load(PNMField(self.fertility_map))
                
        self.root.setShader(self.resources.load_shader('Terrain'))
        self.root.setShaderInput('detail',    16)
        self.root.setShaderInput('size',      self.size)
        self.root.setShaderInput('fertility', texture)
    
    def update(self):
        self.terrain.update()
